import { defineComponent, onUnmounted, ref, watchEffect } from "vue";
import { toRGBAString } from "./utils";

export const Alpha = defineComponent({
    name: 'Alpha',
    props: {
        value: {type: Object},
    },
    emits: ['change'],
    setup (props, { emit }) {
        const left = ref(props.value.hsl.a * 100);

        const gradientStyle = () => {
            const {r, g, b} = props.value.rgba;
            const start = toRGBAString({r, g, b, a: 0});
            const finish = toRGBAString({r, g, b, a: 1});
            return { background: `linear-gradient(to right, ${start} 0%, ${finish} 100%)` };
        };

        let container: any;
        const handleMouseDown = (e: any) => {
            if (typeof e.button === 'number' && e.button !== 0) return false;
            handleChange(e);

            document.addEventListener('mousemove', handleChange, false);
            document.addEventListener('mouseup', onDragEnd, false);
        };

        const onDragEnd = (e: any) => {
            handleChange(e);
            document.removeEventListener('mousemove', handleChange);
            document.removeEventListener('mouseup', onDragEnd);
        };

        onUnmounted(() => {
            document.removeEventListener('mousemove', handleChange);
            document.removeEventListener('mouseup', onDragEnd);
        });

        const handleChange = (e: any) => {
            e.preventDefault();
            e.stopPropagation();

            const { clientWidth } = container;
            const xOffset = container.getBoundingClientRect().left + window.screenX;
            const left = e.clientX - xOffset;
            if (left < 0) {
                change(0);
                return;
            }
            if (left > clientWidth) {
                change(1);
                return;
            }


            change(Math.round(left * 100 / clientWidth) / 100);
        };

        const change = (newAlpha: number) => {
            left.value = newAlpha * 100;

            const {h, s, l, a} = props.value.hsl;
            if (a !== newAlpha) {
                emit('change', {h, s, l, a: newAlpha, source: 'rgba'});
            }
        };

        watchEffect(() => {
            left.value = props.value.hsl.a * 100;
        });

        return () => <div class="cm-color-picker-alpha" ref={(el) => container = el}>
            <div class="cm-color-picker-alpha-wrap" style={gradientStyle()} onMousedown={handleMouseDown}>
                <div class="cm-color-picker-alpha-picker" style={{left: `${left.value}%`, top: '0px'}}></div>
            </div>
        </div>;
    }
});
